"""
交易服务API模式定义
==================

基于现有的MainTradingEngine和OmsEngine设计的交易服务API模式
支持订单管理、交易执行、持仓计算、资金管理等核心功能的API接口
"""

from pydantic import BaseModel, Field, validator
from typing import Optional, List, Dict, Any, Union
from decimal import Decimal
from datetime import datetime
from enum import Enum
import uuid


# ==================== 枚举类型定义 ====================

class OrderDirection(str, Enum):
    """订单方向"""
    LONG = "LONG"
    SHORT = "SHORT"


class OrderOffset(str, Enum):
    """开平仓类型"""
    OPEN = "OPEN"
    CLOSE = "CLOSE"
    CLOSETODAY = "CLOSETODAY"
    CLOSEYESTERDAY = "CLOSEYESTERDAY"


class OrderType(str, Enum):
    """订单类型"""
    LIMIT = "LIMIT"
    MARKET = "MARKET"
    STOP = "STOP"
    FAK = "FAK"
    FOK = "FOK"


class OrderStatus(str, Enum):
    """订单状态"""
    SUBMITTING = "SUBMITTING"
    SUBMITTED = "SUBMITTED"
    PARTIAL_FILLED = "PARTIAL_FILLED"
    FILLED = "FILLED"
    CANCELLED = "CANCELLED"
    REJECTED = "REJECTED"


class TradeDirection(str, Enum):
    """交易方向"""
    BUY = "BUY"
    SELL = "SELL"


class PositionDirection(str, Enum):
    """持仓方向"""
    LONG = "LONG"
    SHORT = "SHORT"
    NET = "NET"


class GatewayStatus(str, Enum):
    """网关状态"""
    DISCONNECTED = "DISCONNECTED"
    CONNECTING = "CONNECTING"
    CONNECTED = "CONNECTED"
    ERROR = "ERROR"


# ==================== 基础模式类 ====================

class BaseResponse(BaseModel):
    """基础响应模式"""
    success: bool = Field(..., description="操作是否成功")
    message: str = Field("", description="响应消息")
    timestamp: datetime = Field(default_factory=datetime.utcnow, description="响应时间")


class PaginationParams(BaseModel):
    """分页参数"""
    page: int = Field(1, ge=1, description="页码")
    size: int = Field(20, ge=1, le=100, description="每页数量")


class PaginatedResponse(BaseModel):
    """分页响应"""
    total: int = Field(..., description="总数量")
    page: int = Field(..., description="当前页码")
    size: int = Field(..., description="每页数量")
    pages: int = Field(..., description="总页数")


# ==================== 订单相关模式 ====================

class OrderRequest(BaseModel):
    """订单请求模式"""
    symbol: str = Field(..., min_length=1, max_length=50, description="证券代码")
    exchange: str = Field(..., min_length=1, max_length=50, description="交易所")
    direction: OrderDirection = Field(..., description="订单方向")
    offset: Optional[OrderOffset] = Field(None, description="开平仓类型")
    order_type: OrderType = Field(OrderType.LIMIT, description="订单类型")
    volume: Decimal = Field(..., gt=0, description="委托数量")
    price: Optional[Decimal] = Field(None, gt=0, description="委托价格")
    strategy_id: Optional[str] = Field(None, max_length=100, description="策略ID")
    reference: Optional[str] = Field(None, max_length=200, description="引用信息")
    notes: Optional[str] = Field(None, max_length=1000, description="备注")
    
    @validator('price')
    def validate_price(cls, v, values):
        """验证价格"""
        if values.get('order_type') == OrderType.LIMIT and v is None:
            raise ValueError("限价单必须指定价格")
        return v
    
    class Config:
        schema_extra = {
            "example": {
                "symbol": "000001",
                "exchange": "SZSE",
                "direction": "LONG",
                "offset": "OPEN",
                "order_type": "LIMIT",
                "volume": "1000",
                "price": "10.50",
                "strategy_id": "strategy_001",
                "reference": "test_order",
                "notes": "测试订单"
            }
        }


class OrderUpdate(BaseModel):
    """订单更新模式"""
    volume: Optional[Decimal] = Field(None, gt=0, description="委托数量")
    price: Optional[Decimal] = Field(None, gt=0, description="委托价格")
    notes: Optional[str] = Field(None, max_length=1000, description="备注")


class OrderCancel(BaseModel):
    """订单撤销模式"""
    reason: Optional[str] = Field(None, max_length=200, description="撤销原因")


class OrderResponse(BaseModel):
    """订单响应模式"""
    id: str = Field(..., description="订单ID")
    order_id: str = Field(..., description="订单编号")
    user_id: str = Field(..., description="用户ID")
    strategy_id: Optional[str] = Field(None, description="策略ID")
    
    # 合约信息
    symbol: str = Field(..., description="证券代码")
    exchange: str = Field(..., description="交易所")
    gateway: Optional[str] = Field(None, description="网关名称")
    
    # 订单信息
    direction: OrderDirection = Field(..., description="订单方向")
    offset: Optional[OrderOffset] = Field(None, description="开平仓类型")
    order_type: OrderType = Field(..., description="订单类型")
    
    # 数量和价格
    volume: Decimal = Field(..., description="委托数量")
    price: Decimal = Field(..., description="委托价格")
    traded_volume: Decimal = Field(..., description="已成交数量")
    remaining_volume: Decimal = Field(..., description="剩余数量")
    average_price: Decimal = Field(..., description="成交均价")
    
    # 状态信息
    status: OrderStatus = Field(..., description="订单状态")
    
    # 时间信息
    created_at: datetime = Field(..., description="创建时间")
    submitted_at: Optional[datetime] = Field(None, description="提交时间")
    updated_at: datetime = Field(..., description="更新时间")
    cancelled_at: Optional[datetime] = Field(None, description="撤销时间")
    
    # 关联信息
    reference: Optional[str] = Field(None, description="引用信息")
    notes: Optional[str] = Field(None, description="备注")
    external_order_id: Optional[str] = Field(None, description="外部订单ID")
    
    class Config:
        from_attributes = True


class OrderListResponse(BaseResponse):
    """订单列表响应"""
    data: List[OrderResponse] = Field(..., description="订单列表")
    pagination: PaginatedResponse = Field(..., description="分页信息")


class OrderDetailResponse(BaseResponse):
    """订单详情响应"""
    data: OrderResponse = Field(..., description="订单详情")


class OrderCreateResponse(BaseResponse):
    """订单创建响应"""
    data: Dict[str, str] = Field(..., description="创建结果")
    
    class Config:
        schema_extra = {
            "example": {
                "success": True,
                "message": "订单创建成功",
                "data": {
                    "order_id": "ORD_20250127_001",
                    "id": "550e8400-e29b-41d4-a716-446655440000"
                }
            }
        }


# ==================== 交易成交相关模式 ====================

class TradeResponse(BaseModel):
    """交易成交响应模式"""
    id: str = Field(..., description="成交ID")
    trade_id: str = Field(..., description="成交编号")
    order_id: str = Field(..., description="订单编号")
    user_id: str = Field(..., description="用户ID")
    
    # 合约信息
    symbol: str = Field(..., description="证券代码")
    exchange: str = Field(..., description="交易所")
    gateway: Optional[str] = Field(None, description="网关名称")
    
    # 交易信息
    direction: TradeDirection = Field(..., description="交易方向")
    offset: Optional[OrderOffset] = Field(None, description="开平仓类型")
    
    # 成交数据
    volume: Decimal = Field(..., description="成交数量")
    price: Decimal = Field(..., description="成交价格")
    turnover: Decimal = Field(..., description="成交金额")
    commission: Decimal = Field(..., description="手续费")
    
    # 时间信息
    trade_time: datetime = Field(..., description="成交时间")
    created_at: datetime = Field(..., description="记录创建时间")
    
    # 外部信息
    external_trade_id: Optional[str] = Field(None, description="外部成交ID")
    
    class Config:
        from_attributes = True


class TradeListResponse(BaseResponse):
    """成交列表响应"""
    data: List[TradeResponse] = Field(..., description="成交列表")
    pagination: PaginatedResponse = Field(..., description="分页信息")


# ==================== 持仓相关模式 ====================

class PositionResponse(BaseModel):
    """持仓响应模式"""
    id: str = Field(..., description="持仓ID")
    user_id: str = Field(..., description="用户ID")
    strategy_id: Optional[str] = Field(None, description="策略ID")
    
    # 合约信息
    symbol: str = Field(..., description="证券代码")
    exchange: str = Field(..., description="交易所")
    gateway: Optional[str] = Field(None, description="网关名称")
    
    # 持仓信息
    direction: PositionDirection = Field(..., description="持仓方向")
    volume: Decimal = Field(..., description="持仓数量")
    frozen: Decimal = Field(..., description="冻结数量")
    
    # 成本信息
    price: Decimal = Field(..., description="持仓均价")
    pnl: Decimal = Field(..., description="持仓盈亏")
    yd_volume: Decimal = Field(..., description="昨仓数量")
    
    # 时间信息
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    
    class Config:
        from_attributes = True


class PositionListResponse(BaseResponse):
    """持仓列表响应"""
    data: List[PositionResponse] = Field(..., description="持仓列表")
    pagination: PaginatedResponse = Field(..., description="分页信息")


# ==================== 资金账户相关模式 ====================

class AccountResponse(BaseModel):
    """资金账户响应模式"""
    id: str = Field(..., description="账户ID")
    account_id: str = Field(..., description="账户编号")
    user_id: str = Field(..., description="用户ID")
    
    # 账户信息
    gateway: str = Field(..., description="网关名称")
    currency: str = Field(..., description="币种")
    
    # 资金信息
    balance: Decimal = Field(..., description="账户余额")
    frozen: Decimal = Field(..., description="冻结资金")
    available: Decimal = Field(..., description="可用资金")
    
    # 统计信息
    total_pnl: Decimal = Field(..., description="总盈亏")
    daily_pnl: Decimal = Field(..., description="当日盈亏")
    commission: Decimal = Field(..., description="手续费")
    
    # 时间信息
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    
    class Config:
        from_attributes = True


class AccountListResponse(BaseResponse):
    """账户列表响应"""
    data: List[AccountResponse] = Field(..., description="账户列表")


# ==================== 合约信息相关模式 ====================

class ContractResponse(BaseModel):
    """合约信息响应模式"""
    id: str = Field(..., description="合约ID")
    symbol: str = Field(..., description="证券代码")
    exchange: str = Field(..., description="交易所")
    
    # 合约基本信息
    name: str = Field(..., description="合约名称")
    product: Optional[str] = Field(None, description="产品代码")
    size: Decimal = Field(..., description="合约乘数")
    pricetick: Decimal = Field(..., description="最小价格变动")
    
    # 交易规则
    min_volume: Decimal = Field(..., description="最小交易量")
    stop_supported: bool = Field(..., description="是否支持止损")
    net_position: bool = Field(..., description="是否净持仓")
    history_data: bool = Field(..., description="是否有历史数据")
    
    # 期权信息
    option_strike: Optional[Decimal] = Field(None, description="期权行权价")
    option_underlying: Optional[str] = Field(None, description="期权标的")
    option_type: Optional[str] = Field(None, description="期权类型")
    option_expiry: Optional[datetime] = Field(None, description="期权到期日")
    
    # 时间信息
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    
    class Config:
        from_attributes = True


class ContractListResponse(BaseResponse):
    """合约列表响应"""
    data: List[ContractResponse] = Field(..., description="合约列表")
    pagination: PaginatedResponse = Field(..., description="分页信息")


# ==================== 网关相关模式 ====================

class GatewayRequest(BaseModel):
    """网关请求模式"""
    gateway_name: str = Field(..., min_length=1, max_length=50, description="网关名称")
    gateway_type: str = Field(..., min_length=1, max_length=50, description="网关类型")
    description: Optional[str] = Field(None, max_length=1000, description="网关描述")
    
    # 连接配置
    host: Optional[str] = Field(None, max_length=200, description="服务器地址")
    port: Optional[int] = Field(None, ge=1, le=65535, description="端口号")
    username: Optional[str] = Field(None, max_length=100, description="用户名")
    password: Optional[str] = Field(None, max_length=200, description="密码")
    
    # 配置信息
    config_json: Optional[Dict[str, Any]] = Field(None, description="配置信息")
    
    class Config:
        schema_extra = {
            "example": {
                "gateway_name": "ctp_test",
                "gateway_type": "CTP",
                "description": "CTP测试网关",
                "host": "180.168.146.187",
                "port": 10131,
                "username": "test_user",
                "password": "test_pass",
                "config_json": {
                    "md_address": "tcp://180.168.146.187:10131",
                    "td_address": "tcp://180.168.146.187:10130",
                    "broker_id": "9999"
                }
            }
        }


class GatewayResponse(BaseModel):
    """网关响应模式"""
    id: str = Field(..., description="网关ID")
    gateway_name: str = Field(..., description="网关名称")
    gateway_type: str = Field(..., description="网关类型")
    description: Optional[str] = Field(None, description="网关描述")
    
    # 连接配置
    host: Optional[str] = Field(None, description="服务器地址")
    port: Optional[int] = Field(None, description="端口号")
    username: Optional[str] = Field(None, description="用户名")
    
    # 状态信息
    status: GatewayStatus = Field(..., description="连接状态")
    is_active: bool = Field(..., description="是否启用")
    
    # 统计信息
    connect_count: int = Field(..., description="连接次数")
    last_connect_time: Optional[datetime] = Field(None, description="最后连接时间")
    last_disconnect_time: Optional[datetime] = Field(None, description="最后断开时间")
    error_message: Optional[str] = Field(None, description="错误信息")
    
    # 时间信息
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    
    class Config:
        from_attributes = True


class GatewayListResponse(BaseResponse):
    """网关列表响应"""
    data: List[GatewayResponse] = Field(..., description="网关列表")


class GatewayConnectRequest(BaseModel):
    """网关连接请求"""
    gateway_name: str = Field(..., description="网关名称")
    force_reconnect: bool = Field(False, description="是否强制重连")


# ==================== 策略相关模式 ====================

class StrategyRequest(BaseModel):
    """策略请求模式"""
    strategy_name: str = Field(..., min_length=1, max_length=200, description="策略名称")
    strategy_class: str = Field(..., min_length=1, max_length=100, description="策略类名")
    description: Optional[str] = Field(None, max_length=1000, description="策略描述")
    parameters_json: Optional[Dict[str, Any]] = Field(None, description="策略参数")
    
    class Config:
        schema_extra = {
            "example": {
                "strategy_name": "MA Cross Strategy",
                "strategy_class": "MACrossStrategy",
                "description": "移动平均线交叉策略",
                "parameters_json": {
                    "fast_window": 5,
                    "slow_window": 20,
                    "symbol": "000001.SZSE"
                }
            }
        }


class StrategyResponse(BaseModel):
    """策略响应模式"""
    id: str = Field(..., description="策略ID")
    strategy_id: str = Field(..., description="策略编号")
    user_id: str = Field(..., description="用户ID")
    
    # 策略信息
    strategy_name: str = Field(..., description="策略名称")
    strategy_class: str = Field(..., description="策略类名")
    description: Optional[str] = Field(None, description="策略描述")
    
    # 策略状态
    is_active: bool = Field(..., description="是否启用")
    is_running: bool = Field(..., description="是否运行中")
    
    # 配置信息
    parameters_json: Optional[Dict[str, Any]] = Field(None, description="策略参数")
    variables_json: Optional[Dict[str, Any]] = Field(None, description="策略变量")
    
    # 统计信息
    total_orders: int = Field(..., description="总订单数")
    total_trades: int = Field(..., description="总成交数")
    total_pnl: Decimal = Field(..., description="总盈亏")
    
    # 时间信息
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    last_run_time: Optional[datetime] = Field(None, description="最后运行时间")
    
    class Config:
        from_attributes = True


class StrategyListResponse(BaseResponse):
    """策略列表响应"""
    data: List[StrategyResponse] = Field(..., description="策略列表")
    pagination: PaginatedResponse = Field(..., description="分页信息")


class StrategyControlRequest(BaseModel):
    """策略控制请求"""
    action: str = Field(..., description="控制动作")
    parameters: Optional[Dict[str, Any]] = Field(None, description="控制参数")
    
    @validator('action')
    def validate_action(cls, v):
        allowed_actions = ['start', 'stop', 'pause', 'resume', 'update_parameters']
        if v not in allowed_actions:
            raise ValueError(f"动作必须是以下之一: {allowed_actions}")
        return v


# ==================== 风控相关模式 ====================

class RiskResponse(BaseModel):
    """风控记录响应模式"""
    id: str = Field(..., description="风控ID")
    user_id: str = Field(..., description="用户ID")
    order_id: Optional[str] = Field(None, description="订单编号")
    
    # 风控信息
    risk_type: str = Field(..., description="风控类型")
    risk_level: str = Field(..., description="风险级别")
    risk_message: str = Field(..., description="风控信息")
    
    # 处理结果
    action_taken: str = Field(..., description="处理动作")
    is_blocked: bool = Field(..., description="是否阻止")
    
    # 相关数据
    symbol: Optional[str] = Field(None, description="证券代码")
    volume: Optional[Decimal] = Field(None, description="数量")
    price: Optional[Decimal] = Field(None, description="价格")
    
    # 时间信息
    created_at: datetime = Field(..., description="创建时间")
    
    class Config:
        from_attributes = True


class RiskListResponse(BaseResponse):
    """风控列表响应"""
    data: List[RiskResponse] = Field(..., description="风控记录列表")
    pagination: PaginatedResponse = Field(..., description="分页信息")


# ==================== 统计分析相关模式 ====================

class TradingStatistics(BaseModel):
    """交易统计模式"""
    total_orders: int = Field(..., description="总订单数")
    active_orders: int = Field(..., description="活跃订单数")
    filled_orders: int = Field(..., description="已成交订单数")
    cancelled_orders: int = Field(..., description="已撤销订单数")
    
    total_trades: int = Field(..., description="总成交数")
    total_volume: Decimal = Field(..., description="总成交量")
    total_turnover: Decimal = Field(..., description="总成交额")
    total_commission: Decimal = Field(..., description="总手续费")
    
    total_pnl: Decimal = Field(..., description="总盈亏")
    daily_pnl: Decimal = Field(..., description="当日盈亏")
    
    active_positions: int = Field(..., description="活跃持仓数")
    total_position_value: Decimal = Field(..., description="持仓总价值")
    
    connected_gateways: int = Field(..., description="已连接网关数")
    active_strategies: int = Field(..., description="活跃策略数")


class TradingStatisticsResponse(BaseResponse):
    """交易统计响应"""
    data: TradingStatistics = Field(..., description="交易统计数据")


# ==================== 查询参数模式 ====================

class OrderQueryParams(PaginationParams):
    """订单查询参数"""
    symbol: Optional[str] = Field(None, description="证券代码")
    exchange: Optional[str] = Field(None, description="交易所")
    status: Optional[OrderStatus] = Field(None, description="订单状态")
    direction: Optional[OrderDirection] = Field(None, description="订单方向")
    strategy_id: Optional[str] = Field(None, description="策略ID")
    start_time: Optional[datetime] = Field(None, description="开始时间")
    end_time: Optional[datetime] = Field(None, description="结束时间")


class TradeQueryParams(PaginationParams):
    """成交查询参数"""
    symbol: Optional[str] = Field(None, description="证券代码")
    exchange: Optional[str] = Field(None, description="交易所")
    direction: Optional[TradeDirection] = Field(None, description="交易方向")
    order_id: Optional[str] = Field(None, description="订单编号")
    start_time: Optional[datetime] = Field(None, description="开始时间")
    end_time: Optional[datetime] = Field(None, description="结束时间")


class PositionQueryParams(PaginationParams):
    """持仓查询参数"""
    symbol: Optional[str] = Field(None, description="证券代码")
    exchange: Optional[str] = Field(None, description="交易所")
    direction: Optional[PositionDirection] = Field(None, description="持仓方向")
    strategy_id: Optional[str] = Field(None, description="策略ID")


class ContractQueryParams(PaginationParams):
    """合约查询参数"""
    symbol: Optional[str] = Field(None, description="证券代码")
    exchange: Optional[str] = Field(None, description="交易所")
    product: Optional[str] = Field(None, description="产品代码")
    keyword: Optional[str] = Field(None, description="关键词搜索")


# ==================== 健康检查和服务信息 ====================

class ServiceHealth(BaseModel):
    """服务健康状态"""
    status: str = Field(..., description="服务状态")
    version: str = Field(..., description="服务版本")
    uptime: float = Field(..., description="运行时间(秒)")
    
    # 数据库状态
    database: Dict[str, Any] = Field(..., description="数据库状态")
    redis: Dict[str, Any] = Field(..., description="Redis状态")
    
    # 业务状态
    active_gateways: int = Field(..., description="活跃网关数")
    active_strategies: int = Field(..., description="活跃策略数")
    pending_orders: int = Field(..., description="待处理订单数")
    
    # 性能指标
    cpu_usage: float = Field(..., description="CPU使用率")
    memory_usage: float = Field(..., description="内存使用率")
    
    class Config:
        schema_extra = {
            "example": {
                "status": "healthy",
                "version": "1.0.0",
                "uptime": 3600.0,
                "database": {"status": "connected", "latency_ms": 5.2},
                "redis": {"status": "connected", "latency_ms": 1.8},
                "active_gateways": 2,
                "active_strategies": 5,
                "pending_orders": 12,
                "cpu_usage": 45.6,
                "memory_usage": 68.3
            }
        }


class ServiceInfo(BaseModel):
    """服务信息"""
    name: str = Field(..., description="服务名称")
    version: str = Field(..., description="版本号")
    description: str = Field(..., description="服务描述")
    start_time: datetime = Field(..., description="启动时间")
    
    # 配置信息
    environment: str = Field(..., description="运行环境")
    debug_mode: bool = Field(..., description="调试模式")
    
    # API信息
    api_version: str = Field(..., description="API版本")
    docs_url: str = Field(..., description="文档地址")
    
    class Config:
        schema_extra = {
            "example": {
                "name": "RedFire Trading Service",
                "version": "1.0.0",
                "description": "RedFire量化交易平台交易服务",
                "start_time": "2025-01-27T10:00:00Z",
                "environment": "development",
                "debug_mode": True,
                "api_version": "v1",
                "docs_url": "/docs"
            }
        }
